package ar.edu.itba.tp1.tpmariano;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import ar.edu.itba.tp1.gps.CalcuDokuEngine;
import ar.edu.itba.tp1.gps.GPSEngine;
import ar.edu.itba.tp1.gps.GPSNode;
import ar.edu.itba.tp1.gps.SearchStrategy;

public class Eternity extends JFrame {

	private static final long serialVersionUID = 1L;

	private JLabel depthLabel;
	private JPanel panel = null;
	private int pathIndex = 0;
	private List<GPSNode> path;

	public Eternity() {
		setSize(525, 430);
		setResizable(false);
		setTitle("Eternity game solver visualizer");
		setLocationRelativeTo(null);
		setLayout(null);
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		depthLabel = new JLabel();
		depthLabel.setBounds(410, 70, 75, 20);
		add(depthLabel);
	}

	public static void main(String args[]) {

		String heuristic = "h3";
		int iterations = 0;
		int seed = 1;
		Problem problem = new Problem();

		if (heuristic.equals("h2")) {
			problem = new Heuristic2Problem();
		} else if (heuristic.equals("h3")) {
			problem = new Heuristic3Problem();
		} else
			problem = new Heuristic1Problem();

		SearchStrategy strategy = SearchStrategy.AStar;

		if (iterations > 0)
			problem.randomize(iterations, seed);

		GPSEngine engine = new CalcuDokuEngine();
		engine.engine(problem, strategy);
	}

	public void showSolution(List<GPSNode> solutionPath) {
		this.path = solutionPath;

		updateGrid((Grid) path.get(pathIndex).getState());

		final JLabel back = new JLabel();
		back.setBounds(410, 10, 50, 50);
		try {
			Image backImage = ImageIO.read(new File("images/back.png"));
			back.setIcon(new ImageIcon(backImage.getScaledInstance(50, 50, java.awt.Image.SCALE_SMOOTH)));
		} catch (IOException e1) {
		}

		back.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				try {
					Image hoverImage = ImageIO.read(new File("images/back_hover.png"));
					back.setIcon(new ImageIcon(hoverImage.getScaledInstance(50, 50, java.awt.Image.SCALE_SMOOTH)));

					setCursor(new Cursor(Cursor.HAND_CURSOR));
				} catch (IOException e1) {
				}
			}

			@Override
			public void mouseExited(MouseEvent e) {
				try {
					Image hoverImage = ImageIO.read(new File("images/back.png"));
					back.setIcon(new ImageIcon(hoverImage.getScaledInstance(50, 50, java.awt.Image.SCALE_SMOOTH)));
					setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
				} catch (IOException e1) {
				}
			}
		});

		back.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (path == null)
					return;

				if (pathIndex > 0) {
					pathIndex--;
					updateGrid((Grid) path.get(pathIndex).getState());
				}
			}
		});
		add(back);

		final JLabel next = new JLabel();
		next.setBounds(460, 10, 50, 50);
		try {
			Image nextImage = ImageIO.read(new File("images/next.png"));
			next.setIcon(new ImageIcon(nextImage.getScaledInstance(50, 50, java.awt.Image.SCALE_SMOOTH)));
		} catch (IOException e1) {
		}

		next.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseEntered(MouseEvent e) {
				try {
					Image hoverImage = ImageIO.read(new File("images/next_hover.png"));
					next.setIcon(new ImageIcon(hoverImage.getScaledInstance(50, 50, java.awt.Image.SCALE_SMOOTH)));
					setCursor(new Cursor(Cursor.HAND_CURSOR));
				} catch (IOException e1) {
				}
			}

			@Override
			public void mouseExited(MouseEvent e) {
				try {
					Image hoverImage = ImageIO.read(new File("images/next.png"));
					next.setIcon(new ImageIcon(hoverImage.getScaledInstance(50, 50, java.awt.Image.SCALE_SMOOTH)));
					setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
				} catch (IOException e1) {
				}
			}
		});
		next.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (path == null)
					return;

				if (pathIndex < path.size() - 1)
					pathIndex++;

				updateGrid((Grid) path.get(pathIndex).getState());
			}
		});
		add(next);
	}

	public void updateGrid(Grid grid) {
		if (panel != null)
			remove(panel);

		panel = new JPanel();
		panel.setLayout(null);
		panel.setBounds(0, 0, 400, 400);
		panel.setVisible(true);
		panel.setBackground(Color.BLACK);
		add(panel);

		for (int y = 3; y >= 0; y--)
			for (int x = 0; x < 4; x++) {
				char tile = grid.getTile(x, y);

				GameTile gTile = new GameTile(x, y, tile);
				gTile.setBounds(x * 100, 300 - y * 100, 100, 100);
				gTile.setVisible(true);
				panel.add(gTile);
			}

		repaint();

		depthLabel.setText("Depth: " + pathIndex);
	}
}
